package com.atom.app.tape;

import static com.atom.app.tape.CameraRulerView.TOUCHPOINT_RADIUS;

import android.graphics.Matrix;

class Circle extends Shape {
    private Point oldCenter = null;
    private Point oldRadiusTangent = null;
    private Point oldRadiusTouch = null;

    public Point center = new Point(0, 0);

    public float radius = 0;

    Point radiusTouchPoint = new Point(0, 0);

    Circle(Point center, float radius) {
        this.center = center;
        this.radius = radius;
        active = true;
        radiusTouchPoint = new Point(center.x + radius + TOUCHPOINT_RADIUS, center.y);
    }

    /**
     * Computes the area of the circle.
     * @return The circle's area.
     */
    public float getArea() {
        return (float) (Math.PI * Math.pow(radius, 2));
    }

    @Override
    public void move(float x, float y) {
        if (oldCenter == null || oldRadiusTouch == null) {
            oldCenter = new Point(center);
            oldRadiusTouch = new Point(radiusTouchPoint);
        }
        center.x = oldCenter.x + x;
        center.y = oldCenter.y + y;
        radiusTouchPoint.x = oldRadiusTouch.x + x;
        radiusTouchPoint.y = oldRadiusTouch.y + y;
    }

    @Override
    public void endMove() {
        oldCenter = null;
        oldRadiusTangent = null;
        oldRadiusTouch = null;
    }

    @Override
    public void zoom(Matrix m) {
        if (oldCenter == null || oldRadiusTangent == null) {
            oldCenter = new Point(center);
            oldRadiusTangent = new Point(getRadiusTangentPoint());
        }
        float[] points = {oldCenter.x, oldCenter.y, oldRadiusTangent.x, oldRadiusTangent.y};
        m.mapPoints(points);
        center.x = points[0];
        center.y = points[1];
        radius = center.dist(new Point(points[2], points[3]));
        adjustRadiusTouchPoint(points[2], points[3]);
    }

    private Point getRadiusTangentPoint() {
        float factor = radius / (radius + TOUCHPOINT_RADIUS);
        return new Point(center.x + factor * (radiusTouchPoint.x - center.x),
                center.y + factor * (radiusTouchPoint.y - center.y));
    }

    private void adjustRadiusTouchPoint(float x, float y) {
        float factor = (radius + TOUCHPOINT_RADIUS) / radius;
        radiusTouchPoint = new Point(center.x + factor * (x - center.x),
                center.y + factor * (y - center.y));
    }
}
